package main

import (
	"context"
	"time"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

type WharfRepo interface {
	GetAll() ([]Wharf, error)
}

type WharfRepoConfig struct {
	MongoURI   string
	DBName     string
	Collection string
	Timeout    time.Duration
}

type WharfRepoStruct struct {
	config      WharfRepoConfig
	mongoClient *mongo.Client
	collection  *mongo.Collection
}

func NewWharfRepo(config WharfRepoConfig) (*WharfRepoStruct, error) {
	uri := config.MongoURI
	opts := options.Client().ApplyURI(uri)
	opts = opts.SetDirect(true)
	client, err := mongo.NewClient(opts)
	if err != nil {
		return nil, err
	}
	ctx, _ := context.WithTimeout(context.Background(), config.Timeout)
	if err != nil {
		return nil, err
	}
	err = client.Connect(ctx)
	if err != nil {
		return nil, err
	}
	db := client.Database(config.DBName)
	coll := db.Collection(config.Collection)
	return &WharfRepoStruct{
		config:      config,
		mongoClient: client,
		collection:  coll,
	}, nil
}

func (w *WharfRepoStruct) GetAll() ([]Wharf, error) {
	ctx, cancel := context.WithTimeout(context.Background(), w.config.Timeout)
	defer cancel()
	filter := bson.M{}
	cursor, err := w.collection.Find(ctx, filter)
	if err != nil {
		return []Wharf{}, err
	}
	wharfs := []Wharf{}
	for cursor.Next(context.TODO()) {
		var wharf Wharf
		err := cursor.Decode(&wharf)
		if err != nil {
			return wharfs, err
		}
		wharfs = append(wharfs, wharf)
	}
	return wharfs, nil
}
